import numpy
def pp(params):
	if len(params)==1:
                params=params[0]

	(init_Eu,tstart)=params	
	
	"""a simple model in which populations Eu and AFR arrive discretely at first generation. If a time is not integer, the migration 
	is divided between neighboring times proportional to the non-integer time fraction. 
	"""
	
	
	tstart*=100
	#print "times ",tstart
	 
	
	if  tstart<0:
		#that should be caught by constraint. Return empty matrix
		gen=int(numpy.ceil(max(tstart,0)))+1
		mig=numpy.zeros((gen+1,2))
		return mig
			
	gen=int(numpy.ceil(tstart))+1
	frac=gen-tstart-1
	mig=numpy.zeros((gen+1,2))
	
	initNat=1-init_Eu
	
	#replace a fraction at second generation to ensure a continuous model distribution with generation	
	mig[-1,:]=numpy.array([init_Eu,initNat])
	mig[-2,:]=frac*numpy.array([init_Eu,initNat])
	
	return mig
	
						
def outofbounds_pp(*params):
	#constraint function evaluating below zero when constraints not satisfied
	ret=1
	params=params[0] #this way of passing parameters seems more robust across platforms
	init_Eu=params[0]
	tstart=params[1]	
	ret=min(1,1-init_Eu)
	ret=min(ret,init_Eu)
	
	
	
	#generate the migration matrix and test for possible issues
	func=pp
	mig=func(params)
	totmig=mig.sum(axis=1)
	
	ret=min(ret,-abs(totmig[-1]-1)+1e-8)
	ret=min(ret,-totmig[0],-totmig[1])
	
	ret=min(ret,10*min(1-totmig),10*min(totmig))
	
	
	
	ret=min(ret,tstart-.02)
	
	
	
	if abs(totmig[-1]-1)>1e-8:
			print mig
			print("founding migration should sum up to 1. Now:")
			
			
	if totmig[0]>1e-10:
			print("migrants at last generation should be removed from sample!")
			
			
		
	if totmig[1]>1e-10:
			print("migrants at penultimate generation should be removed from sample!")
			
			
			
	if ((totmig>1).any() or (mig<0).any()):
			print("migration rates should be between 0 and 1")
		
	return ret
